home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Disktools / PFS / ProgrammersInfo < prev    next >
Text File  |  1996-09-26  |  8KB  |  230 lines

  1. /**********************************************************************/
  2. /* This file contains the datastructures used by PFS                  */
  3. /*                                                                    */
  4. /* If you have specific programming plans I would like to know about  */
  5. /* it. I can help you with any problems and can supply extra          */
  6. /* information, if so needed. I can supply you with PFS specific      */
  7. /* code too, like allocation or anode routines.                       */
  8. /* Of course you're free to do whatever you want with the tools you   */
  9. /* make, but if you'll allow me, I would like to add them to the PFS  */
  10. /* package, or at least refer to it in the documentation.             */
  11. /*                                                                    */
  12. /**********************************************************************/
  13.  
  14. // max length of filename, diskname and comment
  15. #define FNSIZE 108
  16. #define DNSIZE 32
  17. #define CMSIZE 80
  18.  
  19. #define ID_PFS_DISK        (0x50465300L)    //'PFS\0'
  20.  
  21.  
  22. /**********************************************************************/
  23. /*                            Blockformat                             */
  24. /**********************************************************************/
  25.  
  26. #define DBLKID    0x4442    //'DB'
  27. #define ABLKID    0x4142    //'AB'
  28.  
  29.  
  30. /* Directory blocks
  31. **
  32. ** dirblock structure:
  33. **
  34. ** This is what a dirblock looks like on disk. Reserved fields are for
  35. ** future extension.
  36. **
  37. ** DirEntry structure:
  38. **
  39. ** The 'type', 'creationtime' and 'protection' are, accept for their
  40. ** size, in DOS format.
  41. ** The filename and the comment are dynamic: size followed by that
  42. ** number of characters (like BSTRs). The comment directly follows the
  43. ** filename. The 'next' field contains the size of the direntry. This
  44. ** should always be even. The end of the directoryblock is marked by
  45. ** next = 0.
  46. **
  47. ** The size of a direntry can be calculated by:
  48. ** size = (sizeof(struct direntry) + strlen(name) + strlen(comment))&0xfe
  49. */
  50. #define DB_HEADSPACE (6 + 10)
  51. #define DB_ENTRYSPACE (TD_SECTOR - 16)
  52.  
  53. struct dirblock            // voor disk only (WORD blokno), timestamp later..
  54. {
  55.     UWORD id;                    // 'DB'
  56.     ULONG reserved_1[2];
  57.     UWORD reserved_2;
  58.     UWORD anodenr;                // anodenr belonging to this directory (points to FIRST block of dir)
  59.     UWORD parent;                // parent; ANODE_ROOTDIR = root
  60.     UBYTE entries[DB_ENTRYSPACE];    // entries, fini by NULL
  61. };
  62.  
  63. struct direntry
  64. {
  65.     UBYTE next;            // sizeof direntry
  66.     BYTE  type;            // dir, file, link etc
  67.     UWORD anode;        // anode nummer
  68.     ULONG size;            // sizeof file
  69.     UWORD creationday;    // days since Jan. 1, 1978 (ala ADOS; WORD ipv LONG)
  70.     UWORD creationminute; // minutes past midnight
  71.     UWORD creationtick;    // ticks past minute
  72.     UBYTE protection;    // protection bits (ala ADOS)
  73.     UBYTE nlength;        // length of filename
  74.     UBYTE startofname;    // filename, followed by commentlen & comment
  75.     UBYTE pad;            // make size even
  76. };
  77.  
  78. // comment: de is struct direntry *
  79. #define COMMENT(de) ((UBYTE*)(&((de)->startofname) + (de)->nlength))
  80. #define OBJECTNAME(de) ((UBYTE*)(&(de->startofname)))
  81.  
  82. // get a pointer to the next direntry; de = struct direntry *
  83. #define NEXTENTRY(de) ((struct direntry*)((UBYTE*)(de) + (de)->next))
  84.  
  85. // get a pointer to the firste direntry; blok is struct dirblock *
  86. #define FIRSTENTRY(blok) ((struct direntry*)((blok)->blk.entries))
  87.  
  88. #define ENTRYLEN(de, comment) ((sizeof(struct direntry) + (de)->nlength + strlen(comment))&0xfffe)
  89.  
  90.  
  91. /* Anode blocks and Anodes
  92. **
  93. ** All space on disk is allocated by anodes. Anodes are runlength
  94. ** lists: a blocknr and a number indicating how many blocks are
  95. ** allocated by this anode.
  96. **
  97. ** The anodes are organized in an array spread over anodeblocks. The
  98. ** anodenr is the index in this array. The anodeblock themselves are
  99. ** allocated in the rootblock.
  100. **
  101. ** The first 6 anodes have a special function, they allocate
  102. ** freespace, the rootdirectory and perform system functions
  103. **
  104. ** Every anodeblock contains ANODESINBLOCK anodes.
  105. **
  106. ** struct anode:
  107. **
  108. ** The anode itself. The 'clustersize' is the number of blocks being
  109. ** allocated. The allocated blocks are 'blocknr' up to (but not 
  110. ** including)  'blocknr' + 'clustersize'. The 'next' field is a link
  111. ** to another anode where the allocation continues. At the end of the
  112. ** anode chain next = 0.
  113. **
  114. ** If blocknr = 0 the anode is free, and can be reused. If the anode
  115. ** contains { 0, -1, next} the anode is reserved by a file or
  116. ** directory but is not yet in use. PS: empty anodes, with clustersize
  117. ** 0, are valid.
  118. ** Vrijgeven van een anode:  clustersize = 0; blocknr =  0; next = 0;
  119. */
  120.  
  121. #define ANODESINBLOCK    82
  122.  
  123. /* anode 0 is reserved; EOF; must be 0, -1, 0 (use for endoflist detection)
  124. ** ANODE_FREESPACE MUST have ANODE_RESERVED linked. All reserved blocks
  125. ** must be at the end of the chain. There may not be 'mixed' anodes
  126. ** anywhere
  127. **
  128. ** Anodes < 6 may be {0,0,0} but should NEVER be allocated for other
  129. ** purposes.
  130. ** ANODE_FREESPACE, ANODE_BADBLOCKS and ANODE_EOF should always be
  131. ** reserved {0, -1, 0}.
  132. ** ANODE_USERFIRST is the first anode usable for files etc.
  133. */
  134. #define ANODE_EOF            0
  135. #define ANODE_FREESPACE        1
  136. #define ANODE_RESERVED        2
  137. #define ANODE_TOBEFREED        3
  138. #define ANODE_BADBLOCKS        4
  139. #define ANODE_ROOTDIR        5
  140. #define ANODE_USERFIRST        6
  141.  
  142. struct anode
  143. {
  144.     UWORD clustersize;
  145.     UWORD blocknr;
  146.     UWORD next;
  147. };
  148.  
  149.  
  150. struct anodeblock
  151. {
  152.     UWORD id;
  153.     ULONG reserved_1[2];
  154.     UWORD seqnr;        // sequence number of anodeblock (starts with 0)
  155.     UWORD next;            // chain, 0 = end
  156.     UWORD pad;
  157.     struct anode nodes[ANODESINBLOCK];
  158.     ULONG reserved_2;
  159. };
  160.  
  161. /* Data blocks
  162. */
  163. #define DATAINBLOCK    512
  164.  
  165. struct datablock
  166. {
  167.     UBYTE data[DATAINBLOCK];    // only data
  168. };
  169.  
  170.  
  171. /* Rootblock and bootblocks
  172. */
  173. #define BOOTBLOCK1 0
  174. #define BOOTBLOCK2 1
  175. #define ROOTBLOCK 2
  176.  
  177. struct rootblock
  178. {
  179.     LONG  disktype;            // 'FDOS' same place as AmigaDos puts id
  180.     LONG  reserved_1[2];
  181.     UWORD creationday;        // days since Jan. 1, 1978 (ala ADOS; WORD ipv LONG)
  182.     UWORD creationminute;     // minutes past midnight
  183.     UWORD creationtick;        // ticks past minute, not really needed
  184.     UWORD protection;        // protection bits (ala ADOS)
  185.     UBYTE diskname[32];        // DSTR of diskname;
  186.     UWORD firstreserved;    // first reserved block (must be 0)
  187.     UWORD lastreserved;        // end of reserved area
  188.     LONG  reserved_2[10];
  189.     WORD anodeblocks[42];    // 0->notallocated
  190.     UBYTE reserved_3[DATAINBLOCK - 96 - 2*42];
  191. };
  192.  
  193. struct bootblock
  194. {
  195.     LONG disktype;
  196.     UBYTE reserved[508];
  197. };
  198.  
  199.  
  200. /* Reserved areas and other notes
  201. **
  202. ** Anode and directory blocks are allocated in a special reserved area
  203. ** at the start of the partition. The reserved area bounderies are defined
  204. ** in the rootblock and vary with disksize. The reserved area can
  205. ** overflow in the normal area and vice versa.
  206. **
  207. ** Directories are allocated by anodes, but they don't support
  208. ** clustersizes other than 1.
  209. **
  210. ** Allocation strategy
  211. **
  212. ** PFS always always writes directory and anodeblocks in a different
  213. ** place than they came from. The same for files: overwritten files are
  214. ** actually written somewhere else. A kind of 'freed first reused last'
  215. ** (FFRL) algorithm is used, so old versions stay on the disk for a long
  216. ** time. Sometimes PFS will abandon FFRL if this can prevent fragmentation.
  217. ** Recovery tools could make use of this: old versions can be restored
  218. ** if the current one is corrupt, and deleted files can be recovered.
  219. **
  220. ** Update strategy
  221. **
  222. ** Dirty anode and dirblocks are written to disk before the rootblock.
  223. ** Because the rootblock allocates the anodeblock which allocate the
  224. ** directories, and every anode is written on a new position, all
  225. ** changes take effect at the moment the rootblock is written. Before
  226. ** that seemingly nothing has changed.
  227. */
  228.  
  229.  
  230.